Skip to content

Repository files navigation

expression-tools

Deterministic, safe evaluation and analysis of infix math/logic expression strings supplied by a caller with a variable map — e.g. "price * quantity * (1 + tax)" or "age >= 18 && country == 'US'". Built for the Axiom marketplace (handle christiangeorgelucas).

Wraps expr-eval-fork (MIT, zero runtime dependencies) — the actively-maintained, security-patched fork of expr-eval that fixes two 2025 RCE CVEs present in the original library (prototype-pollution via member access, CVE-2025-13204; and unrestricted function invocation from a caller-supplied context, CVE-2025-12735). This package depends on the fork, not the original, deliberately.

Use it from your agent or app

Every node in this package is a live, auto-scaling API endpoint on the Axiom marketplace — call it from an AI agent or your own code, with nothing to self-host.

📦 See it on the marketplace: https://dev.axiomide.com/marketplace/christiangeorgelucas/expression-tools@0.1.0

Hook it up to an AI agent (MCP). Add Axiom's hosted MCP server to any MCP client and every node becomes a typed tool your agent can call — search the catalog, inspect a schema, and invoke it directly.

# Claude Code
claude mcp add --transport http axiom https://api.axiomide.com/mcp \
  --header "Authorization: Bearer $AXIOM_API_KEY"

Claude Desktop, Cursor, or any config-based client:

{
  "mcpServers": {
    "axiom": {
      "type": "http",
      "url": "https://api.axiomide.com/mcp",
      "headers": { "Authorization": "Bearer YOUR_AXIOM_API_KEY" }
    }
  }
}

Call it from the CLI.

axiom invoke christiangeorgelucas/expression-tools/Evaluate --input '{ ... }'

Call it over HTTP.

curl -X POST https://api.axiomide.com/invocations/v1/nodes/christiangeorgelucas/expression-tools/0.1.0/Evaluate \
  -H "Authorization: Bearer $AXIOM_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{ ... }'

Input/output schema for each node is on the marketplace page above, or via axiom inspect node christiangeorgelucas/expression-tools/Evaluate.

Get started free

Install the CLI:

# macOS / Linux — Homebrew
brew install axiomide/tap/axiom

# macOS / Linux — install script
curl -fsSL https://raw.githubusercontent.com/AxiomIDE/axiom-releases/main/install.sh | sh

Windows: download the windows/amd64 .zip from the releases page, unzip it, and put axiom.exe on your PATH.

Then axiom version to verify, axiom login (GitHub or Google) to authenticate, and create an API key under Console → API Keys. Docs and sign-up at axiomide.com.

Nodes

  • Evaluate — evaluate an expression against a caller-supplied variable map, returning a typed result (number, boolean, or string). Covers plain numeric evaluation (no variables), boolean/comparison/logical evaluation, and an optional deterministic result_type coercion.
  • Validate — check whether an expression is syntactically well-formed without evaluating it; reports the parser's line/column on a syntax error when the underlying parser supplies one.
  • ExtractVariables — list every distinct variable name an expression references, and whether it is constant (references none).
  • Substitute — partially evaluate an expression by binding a subset of its variables, returning the reduced expression string and the variables still unbound.
  • Parse — parse an expression into its compiled postfix (RPN) token structure without evaluating it, for inspection/rendering/highlighting.
  • ListCapabilities — list the deterministic operator/function/constant surface this evaluator exposes.

Security posture

This is an eval-adjacent domain, hardened deliberately:

  • Member access disabled (allowMemberAccess: false) — the library's own default is actually true; since every variable this package accepts is a flat scalar, dotted access buys a caller nothing, so the whole "reach through an object" attack class is removed outright.
  • Prototype/constructor access blocked by the fork itself — __proto__, prototype, and constructor identifiers are rejected before evaluation.
  • Functions are allowlisted by the fork — a caller-supplied variable that happens to be a function is never invoked unless it is a registered/safe function.
  • random is removed on every parser instance — the library's one non-deterministic builtin. Every other exposed operator/function/constant is a pure, deterministic math function; there is no clock, network, or filesystem access anywhere in this package.
  • The = assignment operator and inline function-definition syntax are disabled (operators: { assignment: false, fndef: false }). Both are enabled by default in the underlying library, and left enabled an expression like price = 0; price * quantity silently overwrites the "variable" price mid-expression and returns 0 with ok: true instead of the caller's evidently-intended computation — a wrong, non-obvious answer on a thoroughly realistic input (found by independent review, using this package's own worked pricing example). Disabling assignment makes = fail to tokenize at all, so it degrades to a clean parse error instead. ListCapabilities filters its operator lists through the parser's own isOperatorEnabled rather than just listing table keys, for the same reason: a disabled operator remains a key in the underlying tables and would otherwise still be advertised as supported.
  • Length and nesting-depth caps run before an expression ever reaches the parser (2000 chars / 64 levels of (/[ nesting), so a pathological input fails with a structured error instead of a native stack overflow — verified empirically against the installed library (deep nesting throws a raw RangeError around depth ~700–1000; the cap sits well below that).

Every node is a pure, stateless, deterministic single-input → single-output transform.

License

MIT — Copyright (c) 2026 Christian George Lucas. See LICENSE.

About

Deterministic, safe evaluation of infix math/logic expression strings — Axiom marketplace package

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages